from bson.objectid import ObjectId
import requests
from bs4 import BeautifulSoup
import re
from mongo import MongoConn
import time
import queue
import threading
import logging


def get_xrs_id_list(url):
    while True:
        try:
            r = requests.get(url, timeout=100)
            assert r.status_code == 200
            break
        except Exception as e:
            logging.warning('Network error when getting list. Url: ' + url + ' Error: ' + str(e) + 'Retrying..')
    html = r.text
    soup = BeautifulSoup(html, "html.parser")

    info_list = soup.find_all(class_='info')
    return [info.find(class_='btn')['href'].split('/')[-1] for info in info_list]


def get_xrs_question(id_):

    id_ = str(id_)
    url = 'http://tiku.xueersi.com/shiti/' + id_

    r = requests.get(url, timeout=100)
    html = r.text
    soup = BeautifulSoup(html, "html.parser")

    def parse_question(question):
        question = question.strip()
        question = question.replace('单项选择。', '')
        question = re.sub('_{2,}', '<BLANK>', question)
        # 处理两边没有分隔的BLANK
        question = re.sub(r'<BLANK>', ' <BLANK> ', question)
        # 去除多余空格
        question = re.sub(r'\s{1,}', ' ', question)
        # 去除 [ ]
        question = re.sub(r'\[\s*\]', '', question)
        # 合并多个-
        question = re.sub(r'-{2,}', '-', question)
        # 去除首尾空白
        question = question.strip()
        # 题目中的空格数
        blank_num = len(re.findall('<BLANK>', question))
        assert blank_num >= 1
        # 去除中文的
        for c in question:
            assert ord(c) < 256, "有中文"
        return question, blank_num

    def parse_choices(choices, blank_num):
        temp = []
        for index in range(4):
            string1 = chr(ord('A') + index + 0) + '.'
            string2 = chr(ord('A') + index + 1) + '.'
            pos1 = choices.find(string1)
            assert pos1 != -1
            pos2 = choices.find(string2)
            if pos2 == -1:
                temp.append(choices[pos1:])
                break
            else:
                temp.append(choices[pos1:pos2])
        choices = temp
        # choices = re.findall(r'[ABCD]\..*\n', choices)
        choices = [c[2:].strip() for c in choices]

        choice_a = choices[0]
        if len(choice_a.split(',')) == blank_num:
            sep = ','
        elif len(choice_a.split(';')) == blank_num:
            sep = ';'
        else:
            raise Exception("Can't find sep in choice!")

        def __parse_choice_item(choice):
            choice = choice.strip()
            if choice in ['不填', '/']:
                return ''
            else:
                return choice

        if blank_num == 1:
            # 1 的时候单独处理
            choices = [[__parse_choice_item(x) for x in [c]] for c in choices]
        else:
            choices = [[__parse_choice_item(x) for x in c.split(sep)] for c in choices]
        for choice in choices:
            # 每一个选项的个数都要与空格数相称
            assert len(choice) == blank_num
        return choices

    def parse_answer(answer):
        assert answer in ['A', 'B', 'C', 'D']
        return ord(answer) - ord('A')

    content_area = str(soup.find(class_='content-area'))
    content_area = content_area.replace('\xa0', ' ')
    # 还会这样添加下划线
    content_area = re.sub(r'<u>.*?</u>', '___', content_area)
    text = BeautifulSoup(content_area, 'html.parser').get_text()
    text = text.replace('．', '.')
    text = text.replace('—', '-')
    text = text.replace('–', '-')
    text = text.replace('─', '-')
    text = text.replace('（', '(')
    text = text.replace('）', ')')
    text = text.replace('，', ',')
    text = text.replace('。', '.')
    text = text.replace('‘', "'")
    text = text.replace('’', "'")
    text = text.replace('“', '"')
    text = text.replace('”', '"')
    text = text.replace('？', '?')
    text = text.replace('！', '!')
    text = text.replace('；', ";")
    start_string1 = '\n\n[     ]\n\nA.'
    start_string2 = 'A.'
    if text.find(start_string1) != -1:
        start = text.find(start_string1)
        start_len = len(start_string1)
    elif text.find(start_string2) != -1:
        start = text.find(start_string2)
        start_len = len(start_string2)
    else:
        raise Exception("Can't split question and choices!")
    question, blank_num = parse_question(text[0:start])
    choices = parse_choices(text[start + start_len - 2:], blank_num)
    answer = parse_answer(soup.find(class_='answer content-area').get_text().strip())

    return {
        '_id': 'xrs_{}'.format(id_),
        'url': url,
        'question': question,
        'blank_num': blank_num,
        'choices': choices,
        'answer': answer,
    }
